﻿using GamovMvc.Controllers;
using GamovMvc.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Compilation;

namespace GamovMvc
{
    /// <summary>
    /// MvcHandler 的摘要说明
    /// </summary>
    public class MvcHandler : IHttpHandler
    {
        // 路由表
        private IDictionary<string, string> routeData;
        // 所有控制器的类型集合
        private static IList<Type> alloctionControllerTypes;

        static MvcHandler()
        {
            //反射获取所有的Controller
            alloctionControllerTypes = new List<Type>();
            var assemblies = BuildManager.GetReferencedAssemblies();
            foreach (Assembly assembly in assemblies)
            {
                var allTypes = assembly.GetTypes();
                foreach (Type type in allTypes)
                {
                    if (type.IsClass && !type.IsAbstract &&
                        type.IsPublic && typeof(IController).IsAssignableFrom(type))
                    {
                        alloctionControllerTypes.Add(type);
                    }
                }
            }
        }

        public MvcHandler(IDictionary<string, string> routeData)
        {
            this.routeData = routeData;
        }

        public void ProcessRequest(HttpContext context)
        {
            var controllerName = routeData["{controller}"];
            if (string.IsNullOrEmpty(controllerName))
            {
                controllerName = "home";
            }
            IController controller = null;
            foreach (var controllerItem in alloctionControllerTypes)
            {
                if (controllerItem.Name.Equals(string.Format("{0}Controller", controllerName),
                    StringComparison.InvariantCultureIgnoreCase))
                {
                    controller = Activator.CreateInstance(controllerItem) as IController;
                    break;
                }
            }
            var requestContext = new HttpContextBox()
            {
                Context = context,
                RouteData = routeData
            };

            controller.Execute(requestContext);
        }



        public bool IsReusable => false;
    }
}